/***************************************************************************
 *   Copyright (C) 2008/2009 by Philipp Müller                             *
 *   philipp.mueller@gmx.de                                                *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA          *
 ***************************************************************************/

#include <QtCore>
#include <QKeyEvent>

#include "qtvomp.h"
#include "dlgchannelinformation.h"
#include "dlgsettimer.h"
#include "epgdelegate.h"
#include "widgetepg.h"
#include "enterchannelnumber.h"

WidgetEpg::WidgetEpg( MainWindow* mainWindow, QWidget *parent ) : QWidget( parent ),
    m_mainWindow( mainWindow )
{
    m_uiEpg.setupUi( this );

    m_uiEpg.informationButton->setIcon( style()->standardIcon( QStyle::SP_MessageBoxInformation ) );
    m_uiEpg.backButton->setIcon( style()->standardIcon( QStyle::SP_ArrowLeft ) );

    EpgDelegate* epgDelegate = new EpgDelegate( mainWindow, m_uiEpg.epgHeader, this );
    m_uiEpg.epgListView->setModel( m_mainWindow->channelListModel() );
    m_uiEpg.epgListView->setItemDelegate( epgDelegate );

    m_uiEpg.epgListView->setSelectionModel( m_mainWindow->channelListSelectionModel() );
    m_uiEpg.epgListView->setSelectionMode( QAbstractItemView::SingleSelection );
    m_uiEpg.epgListView->setSelectionBehavior( QAbstractItemView::SelectRows );

    m_uiEpg.epgHeader->setMainWindow( m_mainWindow );
    m_uiEpg.epgHeader->setModel( m_mainWindow->channelListModel() );

    //Back
    connect( m_uiEpg.backButton, SIGNAL( clicked() ),
             this,               SLOT( backClicked() ) );

    connect( this,               SIGNAL( back( bool ) ),
             m_mainWindow,       SLOT( displayChannelList( bool ) ) );

    //Information
    connect( m_uiEpg.informationButton, SIGNAL( clicked() ),
            this,                       SLOT( informationClicked() ) );

    //Record
    connect( m_uiEpg.recordButton, SIGNAL( clicked() ),
            this,                  SLOT( setTimer() ) );

    //Clock
    connect( mainWindow->serverTimer(), SIGNAL( timeout() ),
             this,                      SLOT( updateTime() ) );

    //Update of header description
    connect( m_mainWindow->channelListSelectionModel(), SIGNAL( selectionChanged( const QItemSelection &, const QItemSelection & ) ),
             this,                                      SLOT( selectionChanged( const QItemSelection &, const QItemSelection & ) ) );

    //Connect the signal, that an item was pressed with the identification which epg item it is
    connect( m_uiEpg.epgListView, SIGNAL( mousePressEventX( int ) ),
             m_uiEpg.epgHeader,   SLOT( mousePressEventX( int ) ) );

    //Server sent new Epg data
    connect( mainWindow->channelListModel(), SIGNAL( epgListChanged( int ) ),
             this,                           SLOT(   updateEpgDescription( int ) ) );

}


void WidgetEpg::initScreen()
{
    m_uiEpg.epgHeader->setEpgVisibleTime( m_mainWindow->serverTime() );
    m_uiEpg.epgHeader->setEpgSelectionTime( m_mainWindow->serverTime() );

    QModelIndexList selectionList = m_mainWindow->channelListSelectionModel()->selectedIndexes();
    if ( selectionList.size() != ChannelListModel::ChannelColumnsLast )
    {
        qWarning() << "WidgetEpg::keyPressEvent: Wrong selection list size: " << selectionList.size();
        return;
    }
    updateEpgDescription( selectionList[ 0 ].row() );
    m_uiEpg.epgListView->setFocus();
}


void WidgetEpg::updateTime()
{
    m_mainWindow->channelListModel()->epgDataChanged( -1 );
    update();
}


void WidgetEpg::selectionChanged( const QItemSelection & selected, const QItemSelection & /*deselected*/ )
{
    qDebug() << "WidgetEpg::selectionChanged";
    QModelIndexList selectionList = selected.indexes();
    if ( selectionList.size() == 0 )
    {
        qWarning() << "WidgetEpg::selectionChanged: Wrong selection list size: " << selectionList.size();
        return;
    }
    updateEpgDescription( selectionList[ 0 ].row() );
}


void WidgetEpg::informationClicked()
{
    QModelIndexList selectionList = m_mainWindow->channelListSelectionModel()->selectedIndexes();
    if ( selectionList.size() != ChannelListModel::ChannelColumnsLast )
    {
        qWarning() << "WidgetEpg::keyPressEvent: Wrong selection list size: " << selectionList.size();
        return;
    }

    DlgChannelInformation dlg( m_mainWindow, m_uiEpg.epgHeader->currentEpgItem( selectionList[ 0 ].row() ), this );
    dlg.exec();

    m_uiEpg.epgListView->setFocus();
}


void WidgetEpg::backClicked()
{
    emit back( false );
}


void WidgetEpg::keyPressEvent( QKeyEvent * event )
{
    switch ( event->key() )
    {

        case Qt::Key_Left:
        {
            QModelIndexList selectionList = m_mainWindow->channelListSelectionModel()->selectedIndexes();
            if ( selectionList.size() != ChannelListModel::ChannelColumnsLast )
            {
                qWarning() << "WidgetEpg::keyPressEvent: Wrong selection list size: " << selectionList.size();
                return;
            }

            m_uiEpg.epgHeader->selectLeft( selectionList[ 0 ].row() );
            updateEpgDescription( selectionList[ 0 ].row() );
            event->accept();
            return;
        }

        case Qt::Key_Right:
        {
            QModelIndexList selectionList = m_mainWindow->channelListSelectionModel()->selectedIndexes();
            if ( selectionList.size() != ChannelListModel::ChannelColumnsLast )
            {
                qWarning() << "WidgetEpg::keyPressEvent: Wrong selection list size: " << selectionList.size();
                return;
            }

            m_uiEpg.epgHeader->selectRight( selectionList[ 0 ].row() );
            updateEpgDescription( selectionList[ 0 ].row() );
            event->accept();
            return;
        }

        case Qt::Key_0:
        case Qt::Key_1:
        case Qt::Key_2:
        case Qt::Key_3:
        case Qt::Key_4:
        case Qt::Key_5:
        case Qt::Key_6:
        case Qt::Key_7:
        case Qt::Key_8:
        case Qt::Key_9:
        {
            EnterChannelNumber *channel = new EnterChannelNumber( event->text(), m_mainWindow, this );
            channel->exec();
            delete channel;

            event->accept();

            return;
        }

        default:
        {
            QWidget::keyPressEvent( event );
            return;
        }
   }
}


void WidgetEpg::updateEpgDescription( int row )
{
    if( !isVisible() )
    {
        return;
    }

    qDebug() << "WidgetEpg::updateEpgDescription called with row:" << row;
    int currentItem = m_uiEpg.epgHeader->currentEpgItem( row );
    if ( currentItem == -1 )
    {
        m_uiEpg.epgTitle->setText( QString() );
        m_uiEpg.epgDescription->setText( QString() );
        m_uiEpg.epgTime->setText( QString() );
    }
    else
    {
        m_uiEpg.epgTitle->setText( m_mainWindow->channelList()->at( row ).scheduleList[ currentItem ].title );
        m_uiEpg.epgDescription->setText( m_mainWindow->channelList()->at( row ).scheduleList[ currentItem ].description );
        m_uiEpg.epgTime->setText( m_mainWindow->channelListModel()->timeFromTo( row, currentItem ) );
    }
}


void WidgetEpg::setTimer()
{
    qDebug() << "WidgetEpg::setTimer called";

    QModelIndexList selectionList = m_mainWindow->channelListSelectionModel()->selectedIndexes();
    if ( selectionList.size() != ChannelListModel::ChannelColumnsLast )
    {
        qWarning() << "WidgetEpg::keyPressEvent: Wrong selection list size: " << selectionList.size();
        return;
    }

    TimerEntry timer;

    timer.active        = false;
    timer.recording     = false;
    timer.pending       = false;
    timer.channelNumber = m_mainWindow->channelList()->at( selectionList[ 0 ].row() ).channel;
    timer.day           = 0;
    timer.weekDays      = 0;
    timer.file          = m_mainWindow->channelList()->at( selectionList[ 0 ].row() )
                              .scheduleList[ m_uiEpg.epgHeader->currentEpgItem( selectionList[ 0 ].row() ) ].title;

    //Start time
    timer.startTime = m_mainWindow->channelList()->at( selectionList[ 0 ].row() )
                          .scheduleList[ m_uiEpg.epgHeader->currentEpgItem( selectionList[ 0 ].row() ) ].time;

    //Stop time
    timer.stopTime = timer.startTime.addSecs( m_mainWindow->channelList()->at( selectionList[ 0 ].row() )
                                              .scheduleList[ m_uiEpg.epgHeader->currentEpgItem( selectionList[ 0 ].row() ) ].duration );

    //Priority
    QString priority = m_mainWindow->vdr()->loadConfig( "Timers", "Priority" );
    if ( priority.isEmpty() )
    {
        timer.priority = 99;
    }
    else
    {
        timer.priority = priority.toInt();
    }

    //Life time
    QString lifeTime = m_mainWindow->vdr()->loadConfig( "Timers", "Lifetime" );
    if ( lifeTime.isEmpty() )
    {
        timer.lifeTime = 99;
    }
    else
    {
        timer.lifeTime = lifeTime.toInt();
    }

    //Start margin
    QString startMarginString = m_mainWindow->vdr()->loadConfig( "Timers", "Start margin" );
    if ( startMarginString.isEmpty() )
    {
        timer.startTime = timer.startTime.addSecs( -5 * 60 );
    }
    else
    {
        timer.startTime = timer.startTime.addSecs( -startMarginString.toInt() * 60 );
    }

    //End margin
    QString endMarginString   = m_mainWindow->vdr()->loadConfig( "Timers", "End margin" );
    if ( endMarginString.isEmpty() )
    {
        timer.stopTime = timer.stopTime.addSecs( 5 * 60 );
    }
    else
    {
        timer.stopTime = timer.stopTime.addSecs( endMarginString.toInt() * 60 );
    }

    DlgSetTimer dlg( m_mainWindow, timer, DlgSetTimer::New, this );
    dlg.exec();

    m_uiEpg.epgListView->setFocus();
}
